package cn.xuchunh.campusbbs.base;

import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.LayoutManager;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.android.volley.Response;
import com.android.volley.VolleyError;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import cn.xuchunh.campusbbs.R;
import cn.xuchunh.campusbbs.net.HttpRequestManager;
import cn.xuchunh.campusbbs.net.SimpleXJsonListener;
import cn.xuchunh.campusbbs.net.XJsonListener;
import cn.xuchunh.campusbbs.utils.JsonKey;
import cn.xuchunh.campusbbs.widget.LoadingLayout;

/**
 * Created by XuChunH on 2015/9/12.
 */
public abstract class BaseRefreshListFragment<VH extends ViewHolder, T> extends BaseFragment
        implements SwipeRefreshLayout.OnRefreshListener, BaseRecyclerViewAdapter.OnItemClickListener,
        LoadingLayout.OnLoadingStateChangeListener {

    private SwipeRefreshLayout refreshLayout;
    private RecyclerView recyclerView;
    private BaseRecyclerViewAdapter<VH, T> adapter;
    private LoadingLayout loadingLayout;

    private int refreshlayoutId = R.id.refresh_layout;
    private int recyclerViewId = R.id.recycler_view;

    private AtomicBoolean loading;
    private int page = 1;
    private int lastVisibleItem = 0;

    //这里有数据正常显示才算初始化完成
    private boolean inited = false;

    @Override
    protected void beforeInitView() {
        loading = new AtomicBoolean(false);
        setContentViewRes(R.layout.layout_refresh_list);
        adapter = createAdapter();
        if (adapter != null) {
            adapter.setOnItemClickListener(this);
        }
    }

    @Override
    protected View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View contentView = super.createView(inflater, container, savedInstanceState);
        loadingLayout = new LoadingLayout(getActivity());
        loadingLayout.setContentView(contentView);
        loadingLayout.setOnLoadingStateChangeListener(this);
        return loadingLayout;
    }

    @Override
    protected void initView(View view) {
        refreshLayout = (SwipeRefreshLayout) view.findViewById(refreshlayoutId);
        refreshLayout.setOnRefreshListener(this);
        refreshLayout.setColorSchemeResources(R.color.red_500, R.color.blue_500, R.color.yellow_500, R.color.cyan_500);
        recyclerView = (RecyclerView) view.findViewById(recyclerViewId);
        recyclerView.setLayoutManager(createLayoutManager());
        recyclerView.addOnScrollListener(scrollListener);
        recyclerView.setAdapter(adapter);
    }

    @Override
    protected void afterInitView() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                loadData(true);
            }
        }, 500);
    }

    @Override
    public void onDestroyView() {
        inited = false;
        loading.set(false);
        refreshLayout.setRefreshing(false);
        HttpRequestManager.getInstance(getActivity()).cancelRequest(getVolleyTag());
        page = 1;
        super.onDestroyView();
    }

    protected void loadData(boolean fromServer) {
        if (loading.get()) {
            return;
        }
        loading.set(true);
        if (fromServer) {
            loadDataFromServer();
        } else {
            loadDataFromCache();
        }
    }

    protected void loadDataFinished(boolean result, List<T> data) {
        loading.set(false);
        refreshLayout.setRefreshing(false);
        if (result) {
            if (page > 1) {
                adapter.addList(data);
            } else {
                if (data.size() < 1 && !inited) {
                    loadingLayout.setState(LoadingLayout.STATE_EMPTY);
                    return;
                }
                loadingLayout.setState(LoadingLayout.STATE_SHOW_COTNENT);
                inited = true;
                adapter.refresh(data);
            }
            page++;
        } else {
            if (!inited) {
                loadingLayout.setState(LoadingLayout.STATE_FAIL);
            }
        }
    }

    protected abstract LayoutManager createLayoutManager();

    protected abstract BaseRecyclerViewAdapter<VH, T> createAdapter();

    protected abstract List<T> parse(JSONObject jsonObject) throws JSONException;

    protected abstract void loadDataFromServer();

    protected abstract void loadDataFromCache();

    public abstract String getVolleyTag();

    public abstract String getCacheKey();

    /**
     * 当返回的JSON显示获取数据失败时，显示失败原因
     */
    protected void requestDataFail(JSONObject jsonObject) {
        JSONObject head = jsonObject.optJSONObject(JsonKey.HEAD);
        if (head != null) {
            showToast(head.optString(JsonKey.ERR_INFO));
        }
    }

    public BaseRecyclerViewAdapter<VH, T> getAdapter() {
        return adapter;
    }

    public void setAdapter(BaseRecyclerViewAdapter<VH, T> adapter) {
        adapter.setOnItemClickListener(this);
        this.adapter = adapter;
    }

    public void setRefreshlayoutId(int refreshlayoutId) {
        this.refreshlayoutId = refreshlayoutId;
    }

    public void setRecyclerViewId(int recyclerViewId) {
        this.recyclerViewId = recyclerViewId;
    }

    public SwipeRefreshLayout getRefreshLayout() {
        return refreshLayout;
    }

    public RecyclerView getRecyclerView() {
        return recyclerView;
    }

    public boolean isLoading() {
        return loading.get();
    }

    public void setLoading(boolean isLoading) {
        loading.set(isLoading);
    }

    public boolean isInited() {
        return inited;
    }

    public void setInited(boolean inited) {
        this.inited = inited;
    }

    protected LoadingLayout getLoadingLayout() {
        return loadingLayout;
    }

    @Override
    public void onRefresh() {
        if (loading.get()) {
            refreshLayout.setRefreshing(false);
            return;
        }
        page = 1;
        loadData(true);
    }

    @Override
    public void onItemClick(int position, View item) {
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public void setEndableRefreshLayout(boolean enable) {
        if (refreshLayout != null) {
            refreshLayout.setEnabled(enable);
        }
    }

    @Override
    public void onLoadingStateChange(LoadingLayout loadingLayout, int oldState, int currentState) {
        if (!inited) {
            loadData(true);
        }
    }

    public class SimpleListener implements Response.Listener<String> {

        @SuppressWarnings("unchecked")
        @Override
        public void onResponse(String response) {
            boolean result = true;
            List list = null;
            try {
                JSONObject jsonObject = new JSONObject(response);
                if (jsonObject.optInt(JsonKey.RS) == 1) {
                    list = parse(jsonObject);
                } else {
                    requestDataFail(jsonObject);
                    result = false;
                }
            } catch (JSONException ignored) {
                showToast(R.string.error_parse_json);
                result = false;
            } finally {
                loadDataFinished(result, list);
            }
        }
    }

    public class ListXJsonListener extends SimpleXJsonListener<List<T>> {

        @Override
        public List<T> parseData(JSONObject jsonObject) throws Exception {
            return parse(jsonObject);
        }

        @Override
        public void onResponse(List<T> response) {
            loadDataFinished(true, response);
        }
    }

    public class SimpleErrorListener implements Response.ErrorListener {

        @Override
        public void onErrorResponse(VolleyError error) {
            showToast(error.getMessage());
            loadDataFinished(false, null);
        }
    }

    private RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                if (adapter.isNeedFooter()
                        && lastVisibleItem == getAdapter().getItemCount() - 1
                        && adapter.isHasMore()
                        ) {
                    loadData(true);
                }
            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            LayoutManager layoutManager = recyclerView.getLayoutManager();
            if (layoutManager instanceof LinearLayoutManager) {
                lastVisibleItem = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
            }

        }
    };

}
